home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
public
/
SciAn
/
src
/
ScianVisArrows.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
26KB
|
902 lines
/*ScianVisArrows.c
June 14, 1991
Eric Pepke
Routines for arrows visualization object
The arrow object takes a vector field defined over a data form with
any number of topological dimensions, 2 or 3 spatial dimensions, and 2
or 3 components and draws arrows at each point. The arrow visualization
object works for regular data forms, curvilinear data forms, and
nonstructured data forms.
*/
#include "Scian.h"
#include "ScianTypes.h"
#include "ScianArrays.h"
#include "ScianWindows.h"
#include "ScianTextBoxes.h"
#include "ScianObjWindows.h"
#include "ScianIcons.h"
#include "ScianColors.h"
#include "ScianControls.h"
#include "ScianLists.h"
#include "ScianSpaces.h"
#include "ScianSliders.h"
#include "ScianIDs.h"
#include "ScianDatasets.h"
#include "ScianErrors.h"
#include "ScianVisObjects.h"
#include "ScianVisWindows.h"
#include "ScianVisArrows.h"
#include "ScianStyle.h"
#include "ScianPictures.h"
#include "ScianTitleBoxes.h"
#include "ScianButtons.h"
#include "ScianMethods.h"
#include "ScianTemplates.h"
#include "ScianTemplateHelper.h"
#include "ScianSymbols.h"
ObjPtr arrowsClass;
static ObjPtr ArrowsInit(object)
ObjPtr object;
/*Initializes an arrows object*/
{
real bounds[6];
if (GetBounds(object, bounds))
{
real size;
size = bounds[1] - bounds[0];
size = MAX(size, bounds[3] - bounds[2]);
size = MAX(size, bounds[5] - bounds[4]);
SetVar(object, HEADWIDTH, NewReal(size * 0.01));
SetVar(object, SHAFTWIDTH, NewReal(size * 0.005));
SetVar(object, HEADLENGTH, NewReal(size * 0.03));
/****UPDATE*** determine heuristically from dataset*/
SetVar(object, VECTORFACTOR, NewReal(1.0));
}
else
{
SetVar(object, HEADWIDTH, NewReal(0.01));
SetVar(object, SHAFTWIDTH, NewReal(0.005));
SetVar(object, HEADLENGTH, NewReal(0.03));
SetVar(object, VECTORFACTOR, NewReal(0.5));
}
return ObjTrue;
}
static ObjPtr SetArrowsMainDataset(visObj, dataSet)
ObjPtr visObj, dataSet;
/*Sets the main data set of visObj to dataSet*/
{
SetVar(visObj, MAINDATASET, dataSet);
return ObjTrue;
}
static ObjPtr MakeArrowsColored(visObject)
ObjPtr visObject;
/*Makes the arrows colored*/
{
SetVar(visObject, PICCOLORED, ObjTrue);
if (GetPredicate(visObject, COLORS))
{
ObjPtr colorField;
real brightness;
ObjPtr var;
ObjPtr surface;
ObjPtr palette;
/*Get the color field and its form*/
colorField = GetVar(visObject, COLOROBJ);
if (!colorField) return ObjFalse;
/*Get the color palette*/
MakeVar(colorField, CPALETTE);
palette = GetPaletteVar("MakeArrowsColored", colorField, CPALETTE);
if (!palette)
{
return ObjFalse;
}
SetPalette(palette);
/*Get the surface to color*/
surface = GetPictureVar("MakeArrowsColored", visObject, SURFACE);
if (!surface) return ObjFalse;
/*Have to make it colored by the object*/
ColorPictureByObject(surface, colorField, GetPredicate(visObject, INTERPCOLORS));
}
return ObjTrue;
}
static ObjPtr MakeArrowsSurface(visObject)
ObjPtr visObject;
/*Makes the surface in a arrows object. Also colors it.*/
{
ObjPtr dataset; /*The dataset the vis object represents*/
long datasetFlags; /*Flags of the dataset*/
ObjPtr var; /*Random variable*/
ObjPtr picture; /*The picture to be made*/
real shaftWidth, headWidth, headLength, vecFactor;
int nSubdivisions; /*# of subdivisions*/
int arrowStyle; /*Style of arrow*/
int curCapEnds; /*Whether or not to cap ends*/
dataset = GetObjectVar("MakeArrowsSurface", visObject, MAINDATASET);
if (!dataset)
{
return ObjFalse;
}
datasetFlags = GetDatasetInfo(dataset);
if (0 == datasetFlags & DS_HASFORM)
{
ReportError("MakeArrowsSurface", "No data form");
return ObjFalse;
}
/*Make the new picture*/
picture = NewPicture();
if (!picture) return ObjFalse;
var = GetRealVar("MakeArrowsSurface", visObject, SHAFTWIDTH);
if (!var)
{
return ObjFalse;
}
shaftWidth = GetReal(var);
var = GetRealVar("MakeArrowsSurface", visObject, HEADWIDTH);
if (!var)
{
return ObjFalse;
}
headWidth = GetReal(var);
var = GetRealVar("MakeArrowsSurface", visObject, HEADLENGTH);
if (!var)
{
return ObjFalse;
}
headLength = GetReal(var);
var = GetRealVar("MakeArrowsSurface", visObject, VECTORFACTOR);
if (!var)
{
return ObjFalse;
}
vecFactor = GetReal(var);
{
int nTraversalDims;
long *indices;
long *traversalDims;
int whichDim;
int nFormComponents, nDataComponents;
/*Get some parameters*/
var = GetIntVar("MakeArrowsSurface", visObject, FRUSTUMSUBDIV);
if (var)
{
nSubdivisions = GetInt(var);
}
else
{
nSubdivisions = 3;
}
curCapEnds = GetPredicate(visObject, CAPENDSP);
var = GetVar(visObject, STYLE);
if (var)
{
arrowStyle = GetInt(var);
}
else
{
arrowStyle = 0;
}
/*Register the dataset and its dataform*/
if (!SetCurField(FIELD1, dataset))
{
return ObjFalse;
}
if (!SetCurForm(FORMFIELD, dataset))
{
return ObjFalse;
}
/*Get the number of components*/
nFormComponents = GetNComponents(FORMFIELD);
nDataComponents = GetNComponents(FIELD1);
/*Get the information on traversing the dataset*/
nTraversalDims = CountTraversalDims(FORMFIELD);
if (nTraversalDims)
{
traversalDims = (long *) Alloc(sizeof(long) * nTraversalDims);
indices = (long *) Alloc(sizeof(long) * nTraversalDims);
}
else
{
indices = (long *) Alloc(sizeof(long));
}
GetTraversalDims(FORMFIELD, traversalDims);
/*Zero the index*/
for (whichDim = 0; whichDim < nTraversalDims; ++whichDim)
{
indices[whichDim] = 0;
}
do
{
real x1, y1, z1, vx, vy, vz, len, nx, ny, nz;
/*Get the beginning*/
x1 = SelectFieldComponent(FORMFIELD, 0, indices);
y1 = SelectFieldComponent(FORMFIELD, 1, indices);
if (nFormComponents < 3)
{
z1 = 0.0;
}
else
{
z1 = SelectFieldComponent(FORMFIELD, 2, indices);
}
/*Do nothing for missing data*/
if (x1 == missingData ||
y1 == missingData ||
z1 == missingData)
{
goto nextOne;
}
/*Get the vector*/
vx = SelectFieldComponent(FIELD1, 0, indices);
vy = SelectFieldComponent(FIELD1, 1, indices);
if (nDataComponents < 3)
{
vz = 0.0;
}
else
{
vz = SelectFieldComponent(FIELD1, 2, indices);
}
/*Do nothing for missing data*/
if (vx == missingData ||
vy == missingData ||
vz == missingData)
{
goto nextOne;
}
/*Multiply by vector factor*/
vx *= vecFactor;
vy *= vecFactor;
vz *= vecFactor;
/*Get the length*/
len = sqrt(vx * vx + vy * vy + vz * vz);
/*And the normalized vector*/
nx = vx / len;
ny = vy / len;
nz = vz / len;
switch(arrowStyle)
{
case AS_LINE:
{
Vertex vertices[2];
vertices[0] . normal[0] = 0.0;
vertices[0] . normal[1] = 0.0;
vertices[0] . normal[2] = 1.0;
vertices[0] . position[0] = x1;
vertices[0] . position[1] = y1;
vertices[0] . position[2] = z1;
vertices[0] . colorIndex = 0;
vertices[1] . normal[0] = 0.0;
vertices[1] . normal[1] = 0.0;
vertices[1] . normal[2] = 1.0;
vertices[1] . position[0] = x1 + vx;
vertices[1] . position[1] = y1 + vy;
vertices[1] . position[2] = z1 + vz;
vertices[1] . colorIndex = 0;
AppendPolylineToPicture(picture, 1, 0, 2, vertices);
}
break;
case AS_FLAT:
{
int k;
float r[3]; /*Radial unit vector*/
float n[3]; /*Normal unit vector*/
float a[3]; /*Axial unit vector*/
double length, nf;
a[0] = vx;
a[1] = vy;
a[2] = vz;
length = sqrt(a[0]*a[0] + a[1]*a[1] + a[2]*a[2]);
if (length <= 0.0)
{
/*Zero length vector, do nothing*/
break;
}
nf = 1.0 / length;
a[0] *= nf; a[1] *= nf; a[2] *= nf;
/*See if it's nearly colinear with k*/
if (ABS(a[2]) > 0.8)
{
/*It is, so cross by j to get first r*/
r[0] = -a[2];
r[1] = 0.0;
r[2] = a[0];
}
else
{
/*It isn't, so cross by k to get first r*/
r[0] = -a[1];
r[1] = a[0];
r[2] = 0;
}
NORMALIZE(r);
/*Cross a with first radial unit to get orthogonal unit*/
CROSS(a, r, n);
/*Fill in the vertices and draw*/
if (headLength >= len)
{
/*There's no shaft*/
Vertex vertices[3];
/*Set up vertices*/
for (k = 0; k < 3; ++k)
{
vertices[k] . normal[0] = n[0];
vertices[k] . normal[1] = n[1];
vertices[k] . normal[2] = n[2];
vertices[k] . colorIndex = 0;
}
/*Arrow edge*/
vertices[0] . position[0] = x1 - r[0] * headWidth;
vertices[0] . position[1] = y1 - r[1] * headWidth;
vertices[0] . position[2] = z1 - r[2] * headWidth;
/*Arrow tip*/
vertices[1] . position[0] = x1 + vx;
vertices[1] . position[1] = y1 + vy;
vertices[1] . position[2] = z1 + vz;
/*Arrow edge*/
vertices[2] . position[0] = x1 + r[0] * headWidth;
vertices[2] . position[1] = y1 + r[1] * headWidth;
vertices[2] . position[2] = z1 + r[2] * headWidth;
AppendPolyToPicture(picture, 3, vertices);
}
else
{
Vertex vertices[7];
/*Set up vertices*/
for (k = 0; k < 7; ++k)
{
vertices[k] . normal[0] = n[0];
vertices[k] . normal[1] = n[1];
vertices[k] . normal[2] = n[2];
vertices[k] . colorIndex = 0;
}
/*Base corner*/
vertices[0] . position[0] = x1 - r[0] * shaftWidth;
vertices[0] . position[1] = y1 - r[1] * shaftWidth;
vertices[0] . position[2] = z1 - r[2] * shaftWidth;
/*Arrow armpit*/
vertices[1] . position[0] = x1 + vx - headLength * a[0] - r[0] * shaftWidth;
vertices[1] . position[1] = y1 + vy - headLength * a[1] - r[1] * shaftWidth;
vertices[1] . position[2] = z1 + vz - headLength * a[2] - r[2] * shaftWidth;
/*Arrow edge*/
vertices[2] . position[0] = x1 + vx - headLength * a[0] - r[0] * headWidth;
vertices[2] . position[1] = y1 + vy - headLength * a[1] - r[1] * headWidth;
vertices[2] . position[2] = z1 + vz - headLength * a[2] - r[2] * headWidth;
/*Arrow tip*/
vertices[3] . position[0] = x1 + vx;
vertices[3] . position[1] = y1 + vy;
vertices[3] . position[2] = z1 + vz;
/*Arrow edge*/
vertices[4] . position[0] = x1 + vx - headLength * a[0] + r[0] * headWidth;
vertices[4] . position[1] = y1 + vy - headLength * a[1] + r[1] * headWidth;
vertices[4] . position[2] = z1 + vz - headLength * a[2] + r[2] * headWidth;
/*Arrow armpit*/
vertices[5] . position[0] = x1 + vx - headLength * a[0] + r[0] * shaftWidth;
vertices[5] . position[1] = y1 + vy - headLength * a[1] + r[1] * shaftWidth;
vertices[5] . position[2] = z1 + vz - headLength * a[2] + r[2] * shaftWidth;
/*Base corner*/
vertices[6] . position[0] = x1 + r[0] * shaftWidth;
vertices[6] . position[1] = y1 + r[1] * shaftWidth;
vertices[6] . position[2] = z1 + r[2] * shaftWidth;
AppendPolyToPicture(picture, 7, vertices);
}
}
break;
case AS_WIRE:
{
int k;
float r[3]; /*Radial unit vector*/
float n[3]; /*Normal unit vector*/
float a[3]; /*Axial unit vector*/
double length, nf;
a[0] = vx;
a[1] = vy;
a[2] = vz;
length = sqrt(a[0]*a[0] + a[1]*a[1] + a[2]*a[2]);
if (length <= 0.0)
{
/*Zero length vector, do nothing*/
break;
}
nf = 1.0 / length;
a[0] *= nf; a[1] *= nf; a[2] *= nf;
/*See if it's nearly colinear with k*/
if (ABS(a[2]) > 0.8)
{
/*It is, so cross by j to get first r*/
r[0] = -a[2];
r[1] = 0.0;
r[2] = a[0];
}
else
{
/*It isn't, so cross by k to get first r*/
r[0] = -a[1];
r[1] = a[0];
r[2] = 0;
}
NORMALIZE(r);
/*Cross a with first radial unit to get orthogonal unit*/
CROSS(a, r, n);
/*Fill in the vertices and draw*/
if (headLength >= len)
{
/*There's no shaft*/
Vertex vertices[5];
/*Set up vertices*/
for (k = 0; k < 5; ++k)
{
vertices[k] . normal[0] = n[0];
vertices[k] . normal[1] = n[1];
vertices[k] . normal[2] = n[2];
vertices[k] . colorIndex = 0;
}
/*Base*/
vertices[0] . position[0] = x1;
vertices[0] . position[1] = y1;
vertices[0] . position[2] = z1;
/*Arrow tip*/
vertices[1] . position[0] = x1 + vx;
vertices[1] . position[1] = y1 + vy;
vertices[1] . position[2] = z1 + vz;
/*Arrow edge*/
vertices[2] . position[0] = x1 - r[0] * headWidth;
vertices[2] . position[1] = y1 - r[1] * headWidth;
vertices[2] . position[2] = z1 - r[2] * headWidth;
/*Arrow edge*/
vertices[3] . position[0] = x1 + r[0] * headWidth;
vertices[3] . position[1] = y1 + r[1] * headWidth;
vertices[3] . position[2] = z1 + r[2] * headWidth;
/*Arrow tip*/
vertices[4] . position[0] = x1 + vx;
vertices[4] . position[1] = y1 + vy;
vertices[4] . position[2] = z1 + vz;
AppendPolylineToPicture(picture, 1, 0, 3, vertices);
AppendPolylineToPicture(picture, 1, 0, 2, &(vertices[3]));
}
else
{
Vertex vertices[5];
/*Set up vertices*/
for (k = 0; k < 5; ++k)
{
vertices[k] . normal[0] = n[0];
vertices[k] . normal[1] = n[1];
vertices[k] . normal[2] = n[2];
vertices[k] . colorIndex = 0;
}
/*Base*/
vertices[0] . position[0] = x1;
vertices[0] . position[1] = y1;
vertices[0] . position[2] = z1;
/*Arrow tip*/
vertices[1] . position[0] = x1 + vx;
vertices[1] . position[1] = y1 + vy;
vertices[1] . position[2] = z1 + vz;
/*Arrow edge*/
vertices[2] . position[0] = x1 + vx - headLength * a[0] - r[0] * headWidth;
vertices[2] . position[1] = y1 + vy - headLength * a[1] - r[1] * headWidth;
vertices[2] . position[2] = z1 + vz - headLength * a[2] - r[2] * headWidth;
/*Arrow edge*/
vertices[3] . position[0] = x1 + vx - headLength * a[0] + r[0] * headWidth;
vertices[3] . position[1] = y1 + vy - headLength * a[1] + r[1] * headWidth;
vertices[3] . position[2] = z1 + vz - headLength * a[2] + r[2] * headWidth;
/*Arrow tip*/
vertices[4] . position[0] = x1 + vx;
vertices[4] . position[1] = y1 + vy;
vertices[4] . position[2] = z1 + vz;
AppendPolylineToPicture(picture, 1, 0, 3, vertices);
AppendPolylineToPicture(picture, 1, 0, 2, &(vertices[3]));
}
}
break;
case AS_SOLID:
if (headLength >= len)
{
/*There's no shaft*/
float end1[3], rad1, end2[3], rad2;
end1[0] = x1;
end1[1] = y1;
end1[2] = z1;
rad1 = headWidth;
end2[0] = x1 + vx;
end2[1] = y1 + vy;
end2[2] = z1 + vz;
rad2 = 0.0;
ConvertFrustumOntoPicture(picture, end1, rad1, end2, rad2, nSubdivisions, curCapEnds);
}
else
{
/*There is a shaft*/
float end1[3], rad1, end2[3], rad2;
end1[0] = x1;
end1[1] = y1;
end1[2] = z1;
rad1 = shaftWidth;
end2[0] = x1 + nx * (len - headLength);
end2[1] = y1 + ny * (len - headLength);
end2[2] = z1 + nz * (len - headLength);
rad2 = shaftWidth;
ConvertFrustumOntoPicture(picture, end1, rad1, end2, rad2, nSubdivisions, curCapEnds);
rad2 = headWidth;
end1[0] = x1 + vx;
end1[1] = y1 + vy;
end1[2] = z1 + vz;
rad1 = 0.0;
ConvertFrustumOntoPicture(picture, end1, rad1, end2, rad2, nSubdivisions, curCapEnds);
}
break;
}
nextOne:
/*Advance to next arrow*/
for (whichDim = 0; whichDim < nTraversalDims; ++whichDim)
{
if (traversalDims[whichDim] > 0)
{
if ((++indices[whichDim]) >= traversalDims[whichDim])
{
indices[whichDim] = 0;
}
else
{
break;
}
}
}
} while (whichDim < nTraversalDims); /*Break is based on advance*/
SAFEFREE(traversalDims);
SAFEFREE(indices);
}
SetVar(visObject, SURFACE, picture);
SetVar(picture, REPOBJ, visObject);
return ObjTrue;
}
static ObjPtr AddArrowsControls(arrows, panelContents)
ObjPtr arrows, panelContents;
/*Adds controls appropriate to an arrows object to panelContents*/
{
ObjPtr titleBox, button, radio, var, corral, icon, name, arrowsField, mainDataset;
ObjPtr textBox, defaultIcon;
int width, left, top, bottom, right, mid;
int style;
/*Put in the arrow corral at the top left*/
left = MAJORBORDER;
top = MAJORBORDER;
corral = NewIconCorral(NULLOBJ,
left, left + ONECORRALWIDTH,
CWINHEIGHT - MAJORBORDER - ONECORRALHEIGHT,
CWINHEIGHT - MAJORBORDER, 0);
SetVar(corral, SINGLECORRAL, ObjTrue);
SetVar(corral, TOPDOWN, ObjTrue);
SetVar(corral, NAME, NewString("Arrows Field"));
SetVar(corral, HELPSTRING,
NewString("This corral shows the dataset that is being used to make \
the arrows display. The locations, directions, and lengths of the arrows \
are calculated using this field."));
PrefixList(panelContents, corral);
SetVar(corral, PARENT, panelContents);
SetVar(corral, REPOBJ, arrows);
SetMethod(corral, DROPINCONTENTS, DropInMainDatasetCorral);
/*Create the arrows source text box*/
textBox = NewTextBox(left, left + ONECORRALWIDTH,
CWINHEIGHT - MAJORBORDER - ONECORRALHEIGHT - TEXTBOXSEP - TEXTBOXHEIGHT,
CWINHEIGHT - MAJORBORDER - ONECORRALHEIGHT - TEXTBOXSEP,
0, "Arrows Field Text", "Arrows Field");
PrefixList(panelContents, textBox);
SetVar(textBox, PARENT, panelContents);
SetTextAlign(textBox, CENTERALIGN);
/*Put in an icon that represents the field*/
arrowsField = GetObjectVar("AddArrowsControls", arrows, MAINDATASET);
if (!arrowsField) return ObjFalse;
while (mainDataset = GetVar(arrowsField, MAINDATASET))
{
arrowsField = mainDataset;
}
name = GetStringVar("AddArrowsControls", arrowsField, NAME);
defaultIcon = GetVar(arrowsField, DEFAULTICON);
if (defaultIcon)
{
icon = NewObject(defaultIcon, 0);
SetVar(icon, NAME, name);
}
else
{
icon = NewIcon(0, 0, ICONQUESTION, GetString(name));
}
SetVar(icon, ICONLOC, NULLOBJ);
SetVar(icon, REPOBJ, arrowsField);
DropIconInCorral(corral, icon);
top = CWINHEIGHT - MAJORBORDER - ONECORRALHEIGHT - TEXTBOXSEP - TEXTBOXHEIGHT - MINORBORDER;
left = MAJORBORDER;
/*Create the arrow length factor text box*/
mid = top - EDITBOXHEIGHT / 2;
textBox = NewTextBox(left, left + ACNAMEWIDTH,
mid - TEXTBOXHEIGHT / 2 + EDITBOXDOWN,
mid + TEXTBOXHEIGHT / 2 + EDITBOXDOWN,
0, "Arrow Length Text", "Arrow Length:");
PrefixList(panelContents, textBox);
SetVar(textBox, PARENT, panelContents);
var = GetRealVar("AddArrowControls", arrows, VECTORFACTOR);
if (!var)
{
return ObjFalse;
}
textBox = NewTextBox(left + ACNAMEWIDTH + MINORBORDER,
left + ACNAMEWIDTH + MINORBORDER + ACTEXTWIDTH,
mid - EDITBOXHEIGHT / 2, mid + EDITBOXHEIGHT / 2,
EDITABLE + WITH_PIT + ONE_LINE, "Arrow Length Number", "");
SetVar(textBox, PARENT, panelContents);
PrefixList(panelContents, textBox);
SetTextAlign(textBox, RIGHTALIGN);
SetVar(textBox, HELPSTRING, NewString("This text box alters the length of \
the arrows. The number is the factor multiplied by the vector field to produce the \
displacement to the tip of the arrow."));
AssocTextRealControlWithVar(textBox, arrows, VECTORFACTOR, minusInf, plusInf, TR_NE_TOP | TR_NE_BOTTOM);
top -= EDITBOXHEIGHT + MINORBORDER;
/*Create the shaft width text box*/
mid = top - EDITBOXHEIGHT / 2;
textBox = NewTextBox(left, left + ACNAMEWIDTH,
mid - TEXTBOXHEIGHT / 2 + EDITBOXDOWN,
mid + TEXTBOXHEIGHT / 2 + EDITBOXDOWN,
0, "Shaft Radius Text", "Shaft Radius:");
PrefixList(panelContents, textBox);
SetVar(textBox, PARENT, panelContents);
var = GetRealVar("AddArrowControls", arrows, SHAFTWIDTH);
if (!var)
{
return ObjFalse;
}
textBox = NewTextBox(left + ACNAMEWIDTH + MINORBORDER,
left + ACNAMEWIDTH + MINORBORDER + ACTEXTWIDTH,
mid - EDITBOXHEIGHT / 2, mid + EDITBOXHEIGHT / 2,
EDITABLE + WITH_PIT + ONE_LINE, "Shaft Radius Number", "");
SetVar(textBox, PARENT, panelContents);
PrefixList(panelContents, textBox);
SetTextAlign(textBox, RIGHTALIGN);
SetVar(textBox, HELPSTRING, NewString("This text box controls the radius of \
the arrow shaft. The number is in field coordinates."));
AssocTextRealControlWithVar(textBox, arrows, SHAFTWIDTH, minusInf, plusInf, TR_NE_TOP | TR_NE_BOTTOM);
top -= EDITBOXHEIGHT + MINORBORDER;
/*Create the head radius text box*/
mid = top - EDITBOXHEIGHT / 2;
textBox = NewTextBox(left, left + ACNAMEWIDTH,
mid - TEXTBOXHEIGHT / 2 + EDITBOXDOWN,
mid + TEXTBOXHEIGHT / 2 + EDITBOXDOWN,
0, "Head Radius Text", "Head Radius:");
PrefixList(panelContents, textBox);
SetVar(textBox, PARENT, panelContents);
var = GetRealVar("AddArrowControls", arrows, HEADWIDTH);
if (!var)
{
return ObjFalse;
}
textBox = NewTextBox(left + ACNAMEWIDTH + MINORBORDER,
left + ACNAMEWIDTH + MINORBORDER + ACTEXTWIDTH,
mid - EDITBOXHEIGHT / 2, mid + EDITBOXHEIGHT / 2,
EDITABLE + WITH_PIT + ONE_LINE, "Head Radius Number", "");
SetVar(textBox, PARENT, panelContents);
PrefixList(panelContents, textBox);
SetTextAlign(textBox, RIGHTALIGN);
SetVar(textBox, HELPSTRING, NewString("This text box controls the radius of \
the arrowhead. The number is in field coordinates. To make the arrows look like \
pencil shapes, make this number the same as the shaft radius."));
AssocTextRealControlWithVar(textBox, arrows, HEADWIDTH, minusInf, plusInf, TR_NE_TOP | TR_NE_BOTTOM);
top -= EDITBOXHEIGHT + MINORBORDER;
/*Create the head length text box*/
mid = top - EDITBOXHEIGHT / 2;
textBox = NewTextBox(left, left + ACNAMEWIDTH,
mid - TEXTBOXHEIGHT / 2 + EDITBOXDOWN,
mid + TEXTBOXHEIGHT / 2 + EDITBOXDOWN,
0, "Head Length Text", "Head Length:");
PrefixList(panelContents, textBox);
SetVar(textBox, PARENT, panelContents);
var = GetRealVar("AddArrowControls", arrows, HEADLENGTH);
if (!var)
{
return ObjFalse;
}
textBox = NewTextBox(left + ACNAMEWIDTH + MINORBORDER,
left + ACNAMEWIDTH + MINORBORDER + ACTEXTWIDTH,
mid - EDITBOXHEIGHT / 2, mid + EDITBOXHEIGHT / 2,
EDITABLE + WITH_PIT + ONE_LINE, "Head Length Number", "");
SetVar(textBox, PARENT, panelContents);
PrefixList(panelContents, textBox);
SetTextAlign(textBox, RIGHTALIGN);
SetVar(textBox, HELPSTRING, NewString("This text box controls the length of \
the arrowhead. The number is in field coordinates. To make the arrows look like \
skinny needles, make this number infinity."));
AssocTextRealControlWithVar(textBox, arrows, HEADLENGTH, minusInf, plusInf, 0);
top -= EDITBOXHEIGHT + MINORBORDER;
/*Make the arrows style radio buttons*/
titleBox = TemplateTitleBox(ArrowsTemplate, "Arrow Style");
PrefixList(panelContents, titleBox);
SetVar(titleBox, PARENT, panelContents);
radio = NewRadioButtonGroup("Arrow Style Radio");
PrefixList(panelContents, radio);
SetVar(radio, PARENT, panelContents);
button = TemplateRadioButton(ArrowsTemplate, "Line");
AddRadioButton(radio, button);
SetVar(button, HELPSTRING, NewString("When this button is on, the \
arrows will be drawn as a single line. This is the fastest way of drawing \
arrows."));
button = TemplateRadioButton(ArrowsTemplate, "Wire");
AddRadioButton(radio, button);
SetVar(button, HELPSTRING, NewString("When this button is on, the \
arrows will be drawn in wire frame."));
button = TemplateRadioButton(ArrowsTemplate, "Flat");
AddRadioButton(radio, button);
SetVar(button, HELPSTRING, NewString("When this button is on, the \
arrows will be drawn as flat, shaded, 2-D arrows."));
button = TemplateRadioButton(ArrowsTemplate, "Solid");
AddRadioButton(radio, button);
SetVar(button, HELPSTRING, NewString("When this button is on, the \
arrows will be drawn as solid, shaded, cylindrical 3-D arrows.."));
var = GetVar(arrows, STYLE);
if (!var)
{
SetVar(arrows, STYLE, NewInt(0));
}
AssocDirectControlWithVar(radio, arrows, STYLE);
SetVar(radio, HELPSTRING, NewString("These radio buttons control the \
style of arrows display used. Press a button to change the style."));
return ObjTrue;
}
void InitArrows()
/*Initializes the arrows object*/
{
ObjPtr icon;
/*Class for an arrows object*/
arrowsClass = NewObject(visGeometryClass, 0);
AddToReferenceList(arrowsClass);
SetVar(arrowsClass, NAME, NewString("Arrows"));
SetMethod(arrowsClass, INITIALIZE, ArrowsInit);
SetVar(arrowsClass, DEFAULTICON, icon = NewObject(visIcon, 0));
SetVar(icon, WHICHICON, NewInt(ICONARROWS));
SetVar(icon, NAME, NewString("Arrows"));
SetVar(icon, HELPSTRING,
NewString("This icon represents an arrows object. The arrows object \
shows arrows at samples of a vector field with 2 or 3 components."));
DeclareIndirectDependency(arrowsClass, SURFACE, MAINDATASET, CHANGED);
DeclareIndirectDependency(arrowsClass, SURFACE, MAINDATASET);
DeclareDependency(arrowsClass, SURFACE, VECTORFACTOR);
DeclareDependency(arrowsClass, SURFACE, SHAFTWIDTH);
DeclareDependency(arrowsClass, SURFACE, HEADWIDTH);
DeclareDependency(arrowsClass, SURFACE, HEADLENGTH);
DeclareDependency(arrowsClass, SURFACE, STYLE);
SetMethod(arrowsClass, SURFACE, MakeArrowsSurface);
SetMethod(arrowsClass, PICCOLORED, MakeArrowsColored);
SetMethod(arrowsClass, SETMAINDATASET, SetArrowsMainDataset);
SetVar(arrowsClass, STYLE, NewInt(0));
SetMethod(arrowsClass, ADDCONTROLS, AddArrowsControls);
icon = NewIcon(0, 0, ICONARROWS, "Arrows");
SetVar(arrowsClass, CONTROLICON, icon);
DefineVisMapping(DS_HASFORM | DS_HASFIELD | DS_VECTOR, -1, 3, 3, arrowsClass);
DefineVisMapping(DS_HASFORM | DS_HASFIELD | DS_VECTOR, -1, 2, 3, arrowsClass);
DefineVisMapping(DS_HASFORM | DS_HASFIELD | DS_VECTOR, -1, 3, 2, arrowsClass);
DefineVisMapping(DS_HASFORM | DS_HASFIELD | DS_VECTOR, -1, 2, 2, arrowsClass);
}
void KillArrows()
/*Kills the arrows*/
{
DeleteThing(arrowsClass);
}